#pragma once

class Bone {

	friend class Model;

private:

	glm::mat4 relativeMatrix = glm::mat4(1);
	
	// матрица чистой трансформации, нужна для оптимизации вычислений
	glm::mat4 transformMatrix = glm::mat4(1);
	
	glm::mat4 finalMatrix = glm::mat4(1);

	bool updateFlag = true;
	
	glm::vec3 translate = glm::vec3(0,0,0);

	glm::quat rotate = glm::quat(0,0,0,0);
	
	glm::vec3 scale = glm::vec3(1,1,1);
	
	int parent = -1;
	
	bool load(FILE* f);
	
	void save(FILE* f);
	
public:

	void update();

	void setRelativeMatrix(glm::mat4 matrix);
	
	const glm::mat4& getRelativeMatrix() const;

	void setParent(int p);

	const int getParent() const;

	void setTranslate(const glm::vec3& v);

	const glm::vec3& getTranslate() const;
	
	void setRotate(const glm::quat& v);

	const glm::quat& getRotate() const;
	
	void setScale(const glm::vec3& v);

	const glm::vec3& getScale() const;
	
};

const glm::vec3& Bone::getTranslate() const {
	return translate;
}

const glm::quat& Bone::getRotate() const {
	return rotate;
}

const glm::vec3& Bone::getScale() const {
	return scale;
}

void Bone::setTranslate(const glm::vec3& v){
	updateFlag = true;
	translate = v;
}

void Bone::setRotate(const glm::quat& v){
	updateFlag = true;
	rotate = v;
}

void Bone::setScale(const glm::vec3& v){
	updateFlag = true;
	scale = v;
}

const int Bone::getParent() const{
	return parent;
}

void Bone::setParent(int parentIndex){
	updateFlag = true;
	parent = parentIndex;
}

void Bone::setRelativeMatrix(glm::mat4 matrix){
	updateFlag = true;
	relativeMatrix = matrix;
}
	
const glm::mat4& Bone::getRelativeMatrix() const{
	return relativeMatrix;
}

void Bone::update(){
	updateFlag = true;
}

bool Bone::load(FILE* f){
	if (fread(glm::value_ptr(relativeMatrix),sizeof(relativeMatrix),1,f)!=1)
		return false;
	if (fread(&parent,sizeof(parent),1,f)!=1)
		return false;
	updateFlag = true;
	translate = glm::vec3(0,0,0);
	rotate = glm::quat(0,0,0,0);
	scale = glm::vec3(1,1,1);
	
	return false;	
}
	
void Bone::save(FILE* f){
	fwrite(glm::value_ptr(relativeMatrix),sizeof(relativeMatrix),1,f);
	fwrite(&parent,sizeof(parent),1,f);
}

